package com.qijia.travel.dao.impl;

import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
import com.qijia.travel.common.Constants;
import com.qijia.travel.common.SqlMappedId;
import com.qijia.travel.dao.BaseDAO;
import com.qijia.travel.dao.TravelDbException;
import com.qijia.travel.domain.PageResult;
import com.qijia.travel.domain.example.BaseExample;

public class BaseDaoImpl implements BaseDAO {

	private SqlMapClient sqlMapClient;

	public BaseDaoImpl() throws TravelDbException {
		java.io.Reader reader = null;
		try {
			reader = Resources
					.getResourceAsReader(Constants.SQL_MAP_CONFIG_URL);
		} catch (IOException e) {
			throw new TravelDbException("获取SqlMap client时发生错误", e);
		}
		sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader);
	}

	public SqlMapClient getSqlMapClient() throws TravelDbException {
		return this.sqlMapClient;
	}

	public int countByExample(String SqlMapId, Object example)
			throws TravelDbException {
		try {
			Integer count = (Integer) this.getSqlMapClient().queryForObject(
					SqlMapId, example);
			return count;
		} catch (SQLException e) {
			e.printStackTrace();
			throw new TravelDbException("获取统计数据时发生错误，错误map id[" + SqlMapId
					+ "]", e);
		}
	}

	public int deleteByExample(String SqlMapId, Object example)
			throws TravelDbException {
		try {
			return getSqlMapClient().delete(SqlMapId, example);
		} catch (SQLException e) {
			e.printStackTrace();
			throw new TravelDbException("删除数据时发生错误，错误map id[" + SqlMapId + "]",
					e);
		}
	}

	public int deleteByPrimaryKey(String SqlMapId, Object guideId)
			throws TravelDbException {
		return deleteByExample(SqlMapId, guideId);
	}

	public void insert(String SqlMapId, Object record) throws TravelDbException {
		try {
			getSqlMapClient().insert(SqlMapId, record);
		} catch (SQLException e) {
			e.printStackTrace();
			throw new TravelDbException("添加数据时发生错误，错误map id[" + SqlMapId + "]",
					e);
		}
	}

	public PageResult selectByPage(PageResult page) throws TravelDbException {
		if (page == null)
			throw new TravelDbException("page parameter can not be null!");
		else if (null == page.getCountMappedId()
				|| null == page.getSelectDataMappedId())
			throw new TravelDbException("Mapped Id can not be null!");
		try {
			page.setRowCnt(this.countByExample(page.getCountMappedId(), page
					.getSqlParamObj()));

			if (page.getSqlParamObj() instanceof BaseExample) {
				BaseExample example = (BaseExample) page.getSqlParamObj();
				example.setPageSize(page.getPageSize());
				example.setStartLine(page.getStartRow());
				page.setSqlParamObj(example);
			}
			page.setPageList(this.selectByExample(page.getSelectDataMappedId(),
					page.getSqlParamObj()));
			return page;
		} catch (TravelDbException e) {
			e.printStackTrace();
			throw new TravelDbException("查询数据分页列表时发生错误，错误map id["
					+ page.getCountMappedId() + "]", e);
		}
	}

	@SuppressWarnings("unchecked")
	public List<Object> selectByExample(String SqlMapId, Object example)
			throws TravelDbException {
		try {
			return getSqlMapClient().queryForList(SqlMapId, example);
		} catch (SQLException e) {
			e.printStackTrace();
			throw new TravelDbException("查询数据列表时发生错误，错误map id[" + SqlMapId
					+ "]", e);
		}
	}

	public Object selectByPrimaryKey(String SqlMapId, Object guideId)
			throws TravelDbException {
		try {
			return getSqlMapClient().queryForObject(SqlMapId, guideId);
		} catch (SQLException e) {
			e.printStackTrace();
			throw new TravelDbException("以主键查询数据时发生错误，错误map id[" + SqlMapId
					+ "]", e);
		}
	}

	public int updateByPrimaryKey(String SqlMapId, Object record)
			throws TravelDbException {
		try {
			return getSqlMapClient().update(SqlMapId, record);
		} catch (SQLException e) {
			e.printStackTrace();
			throw new TravelDbException(
					"以主键为条件更新数据时(无论参数是否为空都修改)发生错误，错误map id[" + SqlMapId + "]",
					e);
		}
	}

	public int updateByPrimaryKeySelective(String SqlMapId, Object record)
			throws TravelDbException {
		try {
			return getSqlMapClient().update(SqlMapId, record);
		} catch (SQLException e) {
			e.printStackTrace();
			throw new TravelDbException("以主键为条件更新数据时(参数为空则不修改)发生错误，错误map id["
					+ SqlMapId + "]", e);
		}
	}

	public static void main(String[] args) {
		try {
			BaseDAO dao = new BaseDaoImpl();
			System.out.println(dao.getSqlMapClient());
		} catch (TravelDbException e) {
			e.printStackTrace();
		}
	}

	@SuppressWarnings("unchecked")
	public int getAutoIncrementId(String tableName) throws TravelDbException {
		Map<String, Object> dataMap;
		try {
			dataMap = (Map<String, Object>) getSqlMapClient().queryForObject(
					SqlMappedId.selectTableStatus, tableName);
			System.out.println(tableName + "->" + dataMap);

			Object id = dataMap.get(Constants.AUTO_INCREMENT_CODE);
			if (id instanceof Long)
				return ((Long) id).intValue();
			else if (id instanceof Integer)
				return (Integer) id;
			else
				return 0;
		} catch (SQLException e) {
			e.printStackTrace();
			throw new TravelDbException("获取[" + tableName + "]表自增Id时发生错误!", e);
		}

	}
}
